

package com.hazelcast.internal.diagnostics;

import com.hazelcast.spi.impl.NodeEngineImpl;
import com.hazelcast.spi.impl.operationservice.impl.InvocationRegistry;
import com.hazelcast.spi.impl.operationservice.impl.OperationServiceImpl;
import com.hazelcast.spi.properties.HazelcastProperties;
import com.hazelcast.spi.properties.HazelcastProperty;

import static java.util.concurrent.TimeUnit.SECONDS;

/**
 * A {@link DiagnosticsPlugin} that displays invocation latency information.
 */
public class InvocationProfilerPlugin extends DiagnosticsPlugin {

    public static final HazelcastProperty PERIOD_SECONDS = new HazelcastProperty("hazelcast.diagnostics.invocation-profiler.period.seconds", 5, SECONDS);

    private final InvocationRegistry invocationRegistry;
    private long periodMs;
    private HazelcastProperties properties;

    public InvocationProfilerPlugin(NodeEngineImpl nodeEngine) {
        super(nodeEngine.getConfig().getDiagnosticsConfig(), nodeEngine.getLogger(InvocationProfilerPlugin.class));
        OperationServiceImpl operationService = nodeEngine.getOperationService();
        this.invocationRegistry = operationService.getInvocationRegistry();
        this.properties = nodeEngine.getProperties();
        this.periodMs = this.properties.getMillis(overrideProperty(PERIOD_SECONDS));
    }

    @Override
    public long getPeriodMillis() {
        return periodMs;
    }

    @Override
    public void onStart() {
        this.periodMs = this.properties.getMillis(overrideProperty(PERIOD_SECONDS));
        super.onStart();
        logger.info("Plugin:active: period-millis:" + periodMs);
    }

    @Override
    public void onShutdown() {
        super.onShutdown();
        logger.info("Plugin:deactivated: period-millis:" + periodMs);
    }

    @Override
    public void run(DiagnosticsLogWriter writer) {
        writer.startSection("InvocationProfiler");
        OperationProfilerPlugin.write(writer, invocationRegistry.latencyDistributions());
        writer.endSection();
    }

}

